<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>量化交易策略回测结果</title>
    <style>
        /* 基础样式调整：提升整体亮度 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: "SimHei", "Microsoft YaHei", sans-serif;
        }

        /* 动态科技感背景容器 */
        .background-container {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -2;
            background-color: #101828; /* 稍亮的深蓝底色 */
            overflow: hidden;
        }

        /* 动态网格线条（弱化处理，作为基础层） */
        .grid-lines {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-image:
                linear-gradient(to right, rgba(46, 134, 171, 0.08) 1px, transparent 1px),
                linear-gradient(to bottom, rgba(46, 134, 171, 0.08) 1px, transparent 1px);
            background-size: 60px 60px;
            animation: gridMove 20s linear infinite;
        }

        /* 多角度直线容器 */
        .lines-container {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }

        /* 多角度直线效果 */
        .angled-line {
            position: absolute;
            transform-origin: center;
            border-radius: 2px;
        }

        /* 曲线路径容器 */
        .curved-paths {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }

        /* 曲线样式 */
        .curved-path {
            position: absolute;
            width: 100%;
            height: 100%;
            stroke-width: 1;
            fill: none;
            transform-origin: center;
        }

        /* 增强颗粒效果 */
        .particles {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }

        .particle {
            position: absolute;
            border-radius: 50%;
            animation: float 15s linear infinite, pulse 3s ease-in-out infinite;
        }

        /* 主体内容容器 */
        body {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            min-height: 100vh;
            position: relative;
            color: #f1f5f9;
        }

        /* 标题样式优化 */
        .page-title {
            text-align: center;
            color: #ffffff;
            margin-bottom: 30px;
            font-size: 28px;
            font-weight: bold;
            position: relative;
            padding: 20px 0;
            text-shadow: 0 0 10px rgba(56, 189, 248, 0.3);
        }

        .page-title::after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 50%;
            transform: translateX(-50%);
            width: 120px;
            height: 3px;
            background: linear-gradient(90deg, #2E86AB, #38bdf8);
            border-radius: 3px;
            box-shadow: 0 0 10px rgba(56, 189, 248, 0.5);
        }

        .title-meta {
            text-align: center;
            color: #cbd5e1;
            font-size: 14px;
            margin-top: -25px;
            margin-bottom: 30px;
        }

        /* 曲线图容器优化 */
        .chart-container {
            background: rgba(30, 41, 59, 0.85);
            backdrop-filter: blur(10px);
            padding: 20px;
            border-radius: 12px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2), 0 0 15px rgba(56, 189, 248, 0.1);
            margin-bottom: 30px;
            border: 1px solid rgba(255, 255, 255, 0.1);
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
        }

        .chart-container::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 4px;
            background: linear-gradient(90deg, #2E86AB, #38bdf8);
            box-shadow: 0 0 10px rgba(56, 189, 248, 0.5);
        }

        .chart-container:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3), 0 0 20px rgba(56, 189, 248, 0.2);
        }

        .chart-container h2 {
            text-align: center;
            color: #ffffff;
            margin-bottom: 15px;
            font-size: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 10px;
        }

        .chart-container h2::before,
        .chart-container h2::after {
            content: '';
            width: 20px;
            height: 2px;
            background-color: #38bdf8;
        }

        .chart-container img {
            width: 100%;
            max-width: 1000px;
            display: block;
            margin: 0 auto;
            border-radius: 8px;
            transition: all 0.5s ease;
            border: 1px solid rgba(255, 255, 255, 0.15);
            box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
        }

        .chart-container img:hover {
            transform: scale(1.01);
        }

        /* 指标数据容器优化 */
        .metrics-container {
            background: rgba(30, 41, 59, 0.85);
            backdrop-filter: blur(10px);
            padding: 20px;
            border-radius: 12px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2), 0 0 15px rgba(244, 114, 182, 0.1);
            border: 1px solid rgba(255, 255, 255, 0.1);
            transition: all 0.3s ease;
            position: relative;
            margin-bottom: 30px;
        }

        .metrics-container::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 4px;
            background: linear-gradient(90deg, #A23B72, #f472b6);
            box-shadow: 0 0 10px rgba(244, 114, 182, 0.5);
        }

        .metrics-container:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3), 0 0 20px rgba(244, 114, 182, 0.2);
        }

        .metrics-container h2 {
            text-align: center;
            color: #ffffff;
            margin-bottom: 20px;
            font-size: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 10px;
        }

        .metrics-container h2::before,
        .metrics-container h2::after {
            content: '';
            width: 20px;
            height: 2px;
            background-color: #f472b6;
        }

        .metrics-table {
            width: 100%;
            border-collapse: collapse;
            text-align: center;
        }

        .metrics-table th, .metrics-table td {
            padding: 15px 15px;
            border: 1px solid rgba(255, 255, 255, 0.1);
            transition: all 0.3s ease;
        }

        .metrics-table th {
            background-color: rgba(46, 134, 171, 0.15);
            color: #ffffff;
            font-weight: bold;
            font-size: 15px;
        }

        .metrics-table tr:hover td {
            background-color: rgba(255, 255, 255, 0.05);
        }

        .metrics-table tr:nth-child(even) {
            background-color: rgba(255, 255, 255, 0.03);
        }

        /* 策略数据样式 */
        .dqn-color {
            color: #38bdf8;
            font-weight: bold;
            position: relative;
            padding: 5px 0;
            text-shadow: 0 0 5px rgba(56, 189, 248, 0.3);
        }

        .dqn-color::after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 50%;
            transform: translateX(-50%);
            width: 0;
            height: 2px;
            background-color: #38bdf8;
            transition: width 0.3s ease;
        }

        .dqn-color:hover::after {
            width: 100%;
        }

        .bah-color {
            color: #f472b6;
            font-weight: bold;
            position: relative;
            padding: 5px 0;
            text-shadow: 0 0 5px rgba(244, 114, 182, 0.3);
        }

        .bah-color::after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 50%;
            transform: translateX(-50%);
            width: 0;
            height: 2px;
            background-color: #f472b6;
            transition: width 0.3s ease;
        }

        .bah-color:hover::after {
            width: 100%;
        }

        /* 加载状态样式 */
        .loading {
            text-align: center;
            color: #cbd5e1;
            padding: 50px 0;
            font-size: 16px;
            position: relative;
        }

        .loading::after {
            content: '';
            position: absolute;
            width: 24px;
            height: 24px;
            border: 3px solid rgba(46, 134, 171, 0.3);
            border-radius: 50%;
            border-top-color: #38bdf8;
            animation: spin 1s ease-in-out infinite;
            top: 50%;
            left: 50%;
            margin-top: -30px;
            margin-left: -12px;
            box-shadow: 0 0 10px rgba(56, 189, 248, 0.3);
        }

        /* 状态标签组件 */
        .status-tags {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }

        .status-tag {
            background-color: rgba(255, 255, 255, 0.08);
            border: 1px solid rgba(255, 255, 255, 0.15);
            border-radius: 20px;
            padding: 5px 15px;
            font-size: 14px;
            color: #e2e8f0;
            display: flex;
            align-items: center;
            gap: 8px;
            transition: all 0.3s ease;
        }

        .status-tag:hover {
            background-color: rgba(46, 134, 171, 0.15);
            color: #ffffff;
            transform: translateY(-2px);
            box-shadow: 0 0 10px rgba(56, 189, 248, 0.2);
        }

        .status-tag::before {
            content: '';
            width: 8px;
            height: 8px;
            border-radius: 50%;
            box-shadow: 0 0 5px rgba(56, 189, 248, 0.5);
        }

        .tag-dqn::before {
            background-color: #38bdf8;
        }

        .tag-bah::before {
            background-color: #f472b6;
            box-shadow: 0 0 5px rgba(244, 114, 182, 0.5);
        }

        .tag-data::before {
            background-color: #818cf8;
            box-shadow: 0 0 5px rgba(129, 140, 248, 0.5);
        }

        .analysis-content {
        color: #f1f5f9;
        line-height: 1.8;
        padding: 25px;
        border-radius: 8px;
        background-color: rgba(255, 255, 255, 0.03);
        border: 1px solid rgba(255, 255, 255, 0.08);
        font-size: 15px;
        }

        .analysis-content strong {
            color: #38bdf8;
            font-weight: 600;
            font-size: 16px;
        }

        .analysis-content h3 {
            color: #ffffff;
            margin: 20px 0 12px;
            font-size: 17px;
            padding-bottom: 5px;
            border-bottom: 1px solid rgba(56, 189, 248, 0.2);
        }

        .analysis-content p {
            margin: 10px 0;
            text-align: justify;
        }

        .analysis-content ul {
            margin: 10px 0 15px 20px;
            padding-left: 15px;
        }

        .analysis-content li {
            margin: 8px 0;
            position: relative;
            padding-left: 15px;
        }

        .analysis-content li::before {
            content: '•';
            color: #f472b6;
            position: absolute;
            left: 0;
            font-size: 18px;
            line-height: 1;
        }

        .analysis-intro {
            font-style: italic;
            color: #cbd5e1;
            margin-bottom: 15px;
            padding: 10px;
            background-color: rgba(255, 255, 255, 0.02);
            border-left: 3px solid #818cf8;
        }

        /* 动画关键帧 */
        @keyframes gridMove {
            0% { background-position: 0 0; }
            100% { background-position: 60px 60px; }
        }

        /* 旋转动画 */
        @keyframes rotate {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }

        /* 脉冲动画 */
        @keyframes pulse {
            0%, 100% { opacity: 0.2; }
            50% { opacity: 0.6; }
        }

        /* 颗粒漂浮动画 */
        @keyframes float {
            0% {
                transform: translate(0, 0);
                opacity: 0;
            }
            20% {
                opacity: 0.9;
            }
            80% {
                opacity: 0.9;
            }
            100% {
                transform: translate(calc(var(--dx) * 1px), calc(var(--dy) * 1px));
                opacity: 0;
            }
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <!-- 动态背景组件 -->
    <div class="background-container">
        <div class="grid-lines"></div>
        <!-- 多角度直线容器 -->
        <div class="lines-container" id="lines-container"></div>
        <!-- 曲线路径容器 -->
        <div class="curved-paths" id="curved-paths"></div>
        <!-- 增强颗粒 -->
        <div class="particles" id="particles"></div>
    </div>

    <!-- 页面标题 -->
    <h1 class="page-title">基于DQN的多资产量化交易策略回测</h1>
    <div class="title-meta">高级算法交易策略性能分析 · 实时数据更新</div>

    <!-- 状态标签组件 -->
    <div class="status-tags">
        <div class="status-tag tag-dqn">DQN策略已优化</div>
        <div class="status-tag tag-bah">基准策略：买入并持有</div>
        <div class="status-tag tag-data">数据周期：2020-2023</div>
    </div>

    <!-- 曲线图区域 -->
    <div class="chart-container">
        <h2>资金曲线与训练损失对比</h2>
        <div id="chart-loading" class="loading">曲线图加载中...</div>
        <img
            src="/static/quant_results.png"
            alt="量化策略回测曲线图"
            onload="document.getElementById('chart-loading').style.display='none'"
            onerror="document.getElementById('chart-loading').textContent='曲线图加载失败，请刷新页面'"
        >
    </div>

    <!-- 指标数据区域 -->
    <div class="metrics-container">
        <h2>策略绩效指标对比</h2>
        <div id="metrics-loading" class="loading">指标数据加载中...</div>
        <table class="metrics-table" id="metrics-table" style="display: none;">
            <thead>
                <tr>
                    <th>绩效指标</th>
                    <th>DQN策略</th>
                    <th>买入并持有策略</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>年化收益率（%）</td>
                    <td class="dqn-color" id="dqn-annual-return">-</td>
                    <td class="bah-color" id="bah-annual-return">-</td>
                </tr>
                <tr>
                    <td>夏普比率</td>
                    <td class="dqn-color" id="dqn-sharpe">-</td>
                    <td class="bah-color" id="bah-sharpe">-</td>
                </tr>
                <tr>
                    <td>最大回撤（%）</td>
                    <td class="dqn-color" id="dqn-max-drawdown">-</td>
                    <td class="bah-color" id="bah-max-drawdown">-</td>
                </tr>
            </tbody>
        </table>
    </div>

    <!-- 大模型分析结果区域 -->
    <div class="chart-container">
        <h2>大模型策略分析</h2>
        <div id="analysis-loading" class="loading">分析结果加载中...</div>
        <div id="llm-analysis" class="analysis-content" style="display: none;"></div>
    </div>

    <script>
        // 创建多角度直线
        function createAngledLines() {
            const container = document.getElementById('lines-container');
            const lineCount = 20;
            const angles = [0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180];

            for (let i = 0; i < lineCount; i++) {
                const line = document.createElement('div');
                line.className = 'angled-line';

                // 随机属性
                const angle = angles[Math.floor(Math.random() * angles.length)];
                const length = Math.random() * 60 + 40; // 40-100%
                const width = Math.random() * 2 + 0.5; // 0.5-2.5px
                const top = Math.random() * 100;
                const left = Math.random() * 100;
                const duration = Math.random() * 120 + 60; // 60-180s
                const delay = Math.random() * 20;
                const opacity = Math.random() * 0.3 + 0.1;

                // 线条颜色变化
                const colors = [
                    `linear-gradient(90deg, transparent, rgba(56, 189, 248, ${opacity}), transparent)`,
                    `linear-gradient(90deg, transparent, rgba(244, 114, 182, ${opacity}), transparent)`,
                    `linear-gradient(90deg, transparent, rgba(129, 140, 248, ${opacity}), transparent)`
                ];

                line.style.background = colors[Math.floor(Math.random() * colors.length)];
                line.style.width = `${length}%`;
                line.style.height = `${width}px`;
                line.style.top = `${top}%`;
                line.style.left = `${left}%`;
                line.style.transform = `rotate(${angle}deg)`;

                // 随机旋转方向
                const direction = Math.random() > 0.5 ? 1 : -1;
                line.style.animation = `rotate ${duration * direction}s linear ${delay}s infinite, pulse 5s ease-in-out infinite`;

                container.appendChild(line);
            }
        }

        // 创建曲线
        function createCurvedPaths() {
            const container = document.getElementById('curved-paths');
            const pathCount = 10;

            for (let i = 0; i < pathCount; i++) {
                const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                svg.setAttribute('width', '100%');
                svg.setAttribute('height', '100%');

                const path = document.createElementNS("http://www.w3.org/2000/svg", "path");

                // 随机曲线属性
                const startX = Math.random() * 100;
                const startY = Math.random() * 100;
                const cpX1 = Math.random() * 100;
                const cpY1 = Math.random() * 100;
                const cpX2 = Math.random() * 100;
                const cpY2 = Math.random() * 100;
                const endX = Math.random() * 100;
                const endY = Math.random() * 100;

                // 创建贝塞尔曲线路径
                const d = `M ${startX}% ${startY}% C ${cpX1}% ${cpY1}%, ${cpX2}% ${cpY2}%, ${endX}% ${endY}%`;
                path.setAttribute('d', d);

                // 随机颜色
                const colors = [
                    'rgba(56, 189, 248, 0.2)',
                    'rgba(244, 114, 182, 0.2)',
                    'rgba(129, 140, 248, 0.2)'
                ];
                path.setAttribute('stroke', colors[Math.floor(Math.random() * colors.length)]);
                path.className = 'curved-path';

                // 动画属性
                const duration = Math.random() * 200 + 100; // 100-300s
                const delay = Math.random() * 30;
                const direction = Math.random() > 0.5 ? 1 : -1; // 顺时针或逆时针

                svg.style.animation = `rotate ${duration * direction}s linear ${delay}s infinite`;

                svg.appendChild(path);
                container.appendChild(svg);
            }
        }

        // 创建增强颗粒效果
        function createEnhancedParticles() {
            const particlesContainer = document.getElementById('particles');
            const particleCount = 150; // 增加颗粒数量

            for (let i = 0; i < particleCount; i++) {
                const particle = document.createElement('div');
                particle.classList.add('particle');

                // 随机属性
                const size = Math.random() * 4 + 0.5; // 0.5-4.5px
                const x = Math.random() * 100;
                const y = Math.random() * 100;
                const dx = (Math.random() - 0.5) * 1200; // 更大的移动范围
                const dy = (Math.random() - 0.5) * 1200;
                const duration = Math.random() * 30 + 15; // 15-45s
                const delay = Math.random() * 20;

                // 随机颜色，增强视觉层次
                const colors = [
                    'rgba(56, 189, 248, 0.7)',
                    'rgba(244, 114, 182, 0.7)',
                    'rgba(129, 140, 248, 0.7)',
                    'rgba(255, 255, 255, 0.5)'
                ];
                particle.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];

                // 随机添加光晕效果
                if (Math.random() > 0.6) {
                    particle.style.boxShadow = `0 0 12px ${particle.style.backgroundColor}`;
                }

                particle.style.width = `${size}px`;
                particle.style.height = `${size}px`;
                particle.style.left = `${x}%`;
                particle.style.top = `${y}%`;
                particle.style.setProperty('--dx', dx);
                particle.style.setProperty('--dy', dy);
                particle.style.animationDuration = `${duration}s`;
                particle.style.animationDelay = `${delay}s`;

                particlesContainer.appendChild(particle);
            }
        }

        // 页面加载完成后初始化动态元素
        window.addEventListener('load', () => {
            createAngledLines();
            createCurvedPaths();
            createEnhancedParticles();

            // 加载大模型分析结果
            fetch("/api/llm-analysis")
            .then(response => {
                if (!response.ok) throw new Error("分析数据请求失败");
                return response.json();
            })
            .then(data => {
                let formattedAnalysis = data.analysis;

                // 处理标题层级
                formattedAnalysis = formattedAnalysis.replace(/\*\*(.+?):\*\*/g, (match, title) => {
                    if (title.match(/^\d+\.\s/)) {
                        return `<h3>${title}</h3>`;
                    }
                    return `<strong>${title}</strong>`;
                });

                // 处理列表
                formattedAnalysis = formattedAnalysis.replace(/(?:\n|^)-\s(.+?)(?=\n-|\n|$)/g, (match, text) => {
                    return `<li>${text}</li>`;
                });

                // 包裹列表项为ul标签
                formattedAnalysis = formattedAnalysis.replace(/(<li>.+?<\/li>)+/gs, '<ul>$&</ul>');

                // 处理段落分隔
                formattedAnalysis = formattedAnalysis.replace(/\n{2,}/g, '</p><p>');
                formattedAnalysis = `<p>${formattedAnalysis}</p>`;

                // 添加引言样式
                if (formattedAnalysis.includes('从量化交易角度分析：')) {
                    formattedAnalysis = formattedAnalysis.replace(
                        '从量化交易角度分析：',
                        '<div class="analysis-intro">从量化交易角度分析：</div>'
                    );
                }

                document.getElementById("llm-analysis").innerHTML = formattedAnalysis;
                document.getElementById("analysis-loading").style.display = "none";
                document.getElementById("llm-analysis").style.display = "block";
            })
            .catch(error => {
                document.getElementById("analysis-loading").textContent = `分析加载失败：${error.message}`;
            });
        });

        // 加载绩效指标数据
        fetch("/api/metrics")
            .then(response => {
                if (!response.ok) throw new Error("数据请求失败");
                return response.json();
            })
            .then(data => {
                document.getElementById("dqn-annual-return").textContent = data.dqn.年化收益率;
                document.getElementById("dqn-sharpe").textContent = data.dqn.夏普比率;
                document.getElementById("dqn-max-drawdown").textContent = data.dqn.最大回撤;
                document.getElementById("bah-annual-return").textContent = data.buy_and_hold.年化收益率;
                document.getElementById("bah-sharpe").textContent = data.buy_and_hold.夏普比率;
                document.getElementById("bah-max-drawdown").textContent = data.buy_and_hold.最大回撤;

                document.getElementById("metrics-loading").style.display = "none";
                document.getElementById("metrics-table").style.display = "table";
                animateNumbers();
            })
            .catch(error => {
                document.getElementById("metrics-loading").textContent = `数据加载失败：${error.message}`;
            });

        // 数字动画效果
        function animateNumbers() {
            const elements = document.querySelectorAll('.dqn-color, .bah-color');
            elements.forEach(el => {
                const target = parseFloat(el.textContent);
                if (!isNaN(target)) {
                    el.textContent = '0';
                    const duration = 1500;
                    const step = target / (duration / 16);
                    let current = 0;
                    const timer = setInterval(() => {
                        current += step;
                        if ((step > 0 && current >= target) || (step < 0 && current <= target)) {
                            clearInterval(timer);
                            current = target;
                        }
                        el.textContent = current.toFixed(2);
                    }, 16);
                }
            });
        }
    </script>
</body>
</html>